/*
  可索引接口以及类类型接口
    我们都知道  接口就是一个规范 用来让工程师都执行的一个规范  所以接口除了课规范前面的属性 函数的形参  还可以规范 数组、对象、以及类
*/

/*
  只要是接口 都是使用 interface 关键字来定义
  可索引接口 - - 主要用来规范数组和对象的  （使用的场景并不是很多）

  类类型接口  ：  用来规范类的一种接口
*/
// 定义数组的索引接口
interface myArr {
  // 定义好了一个数组的接口 规定的数组的索引必须是number类型，值必须是string类型
  [index: number]: string
  /*
    我们会发现 因为数组的索引必须是number类型  所以数组的接口和原生的ts定义想要的效果就是一样了  这个就是使用较少的原因
  */
}
// 之所以使用的比较少的原因就是定义数组的接口和ts原生定义数组功能是一样的
let arrs: string[] = ['5', 'jim', 'hello']
let arrb: Array<number> = [723, 38, 210, 782]
// 以上是原生的方式来定义数组
// 使用接口来规范数组
let interarr: myArr = ['html', 'css', 'javascript']
//let intera:myArr = ['php','vscode',2344] // 报错 因为已经不符合接口定义了

// 定义对象接口
interface myObj {
  [index: string]: string // 定义好了一个对象接口 这个对象接口规定  对象的键名必须是string类型 键值必须是string类型
}
let obj1: myObj = {
  name: 'Jimmy',
  age: '22',
}
// let obj2 = {
//   name: 'XUEXUE',
//   age：22  // 报错 因为不符合接口规范  接口规定了键值必须是string类型
// }

/*
  类类型接口 ： 用来规范类的一种接口， 这个和抽象类的概念很像 基本就是提供模板  让子类去仿照这个模板进行生产
*/
interface myClass {
  /*
    定义一个类类型接口  使用这个接口的类 必须要有 name属性  和  eat方法  否则会报错
  */

  nameaa: string
  eat(str: string): void
}

/*
  类在使用接口的时候使用 需要使用关键字  implements 引用接口 相当于抽象类继承时的 extends
    ！！！！！！  有一个小细节 使用类类型的接口的时候  一定要有接口的每一个属性和方法  但是方法的形参可以不写不会报错  但是写了就必须要保持一致 ！！！！！！
      这个也就是类类型接口和抽象类的区别之一了  抽象类的话必须要保持形参上的完全一致
*/

class fish implements myClass {
  nameaa: string
  constructor(name: string) {
    this.nameaa = name
  }
  eat(): void {
    console.log('hello i am fish')
  }
}
